package org.liveboardgames.agricola.vo.action
{
	import com.adobe.cairngorm.vo.IValueObject;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ListCollectionView;
	
	import org.liveboardgames.agricola.vo.common.Target;
	import org.liveboardgames.common.dictionary.collections.HashCollection;
	import org.liveboardgames.common.dictionary.collections.IMap;

	[RemoteClass(alias="org.liveboardgames.agricola.domain.action.Action")]
	[Bindable]
	public class Action implements IValueObject
	{
		public var id:int;

		public var name:String;

		public var cost:IMap;

		/** 0 for an unlimited number of uses. */
		public var numberOfUses:int;

		public var tempo:String;

		public var needPlayerInput:Boolean = false;

		public var actionOutput:String;

		public var outputQuantity:int = 1;

		/** The entity that will benefit from the action. */
		public var target:Target;

		/**
		 * An element to which the action is intrically linked. For
		 * instance, the TAKE_ALL action needs to know the card from
		 * which to take the resources.
		 */
		public var link:Target;

		/** Either Actions or PrerequisiteEnums.*/
		public var prerequisiteActions:ListCollectionView;

		public var prerequisiteEnums:ListCollectionView;

		public var prerequisiteActionType:String;

		public function Action()
		{
			numberOfUses = 1;
			needPlayerInput = true;
			prerequisiteActions = new ArrayCollection();
			prerequisiteEnums = new ArrayCollection();
		}


		public function addPrerequisiteAction(action:Action):void
		{
			this.prerequisiteActions.addItem(action);
		}

		public function getPrerequisiteActions():ListCollectionView
		{
			return prerequisiteActions;
		}

		/** Really a PrerequisiteEnum */
		public function addPrerequisite(prerequisite:String):void
		{
			this.prerequisiteEnums.addItem(prerequisite);
		}

		public function clone():Action
		{
			var action:Action = new Action();
			populateCloneAction(action);
			return action;
		}
		
		protected function populateCloneAction(action:Action):void
		{
			// Clone the cost
			if (this.cost != null)
			{
				var newCost:IMap = new HashCollection();
				for each (var resource:Object in cost.getKeys())
				{
					newCost.put(resource, cost.getValue(resource) as int);
				}
				action.cost = newCost;
			}

			// Clone the output
			action.actionOutput = this.actionOutput;
			action.outputQuantity = this.outputQuantity;

			// Clone other attributes
			action.tempo = this.tempo;
			action.numberOfUses = this.numberOfUses;

			// No deep copy: the reference to the target is kept, and the 
			// target object is shared
			action.target = this.target;
			action.link = this.link;
			action.prerequisiteActions = this.prerequisiteActions;
			action.prerequisiteEnums = this.prerequisiteEnums;
			action.name = this.name;
		}

		public function equals(object:Object):Boolean
		{
			var result:Boolean = true;

			if (object is Action)
			{
				var comparedToAction:Action = object as Action;
				var isNamesMatching:Boolean = (this.name == comparedToAction.name);
				result = result && (this.name == comparedToAction.name);
			}

			return result;
		}

		public function toString():String
		{
			return this.name;
		}
	}
}